import { resetLongToStr } from "@/utils/biz/common/BizUtils";
import { UserWaitApi } from "@/api/user_api";
import { Observer } from "@/utils/observer/Observer";

/**
 * 候诊屏 -- 全部常规候诊屏交互逻辑实现类
 */
class WaitPatientObserverBiz extends Observer {

  constructor(self, deviceInfo = {}, item) {
    super();
    // 外部组件
    this.catcheInfo = self;
    // 设备信息
    this.deviceInfo = deviceInfo;
    // 当前组件信息
    this.currentInfo = item || {};
    // 私有内存
    this.allWorkerList = [];
  }

  /**
   * 消息监听入口
   * @param bizType
   * @param msgContent
   */
  async update(bizType, msgContent) {
    let self = this.catcheInfo;
    try {
      switch (bizType) {
        case "doctorLogin":
          await this.doctorLogin(msgContent);
          break;
        case "doctorLogout":
          await this.doctorLogout(msgContent);
          break;
        case "pauseDoctor":
          await this.pauseDoctor(msgContent);
          break;
        case "cancelPause":
          await this.cancelPause(msgContent);
          break;
        case "refreshMsg":
          await this.refreshMsg(msgContent);
          break;
        case "updateWaitScreenDoctors":
          // 刷新数据
          await this.updateWaitScreenDoctors(msgContent);
          break;
        case "openMsgWin":
          await this.openMsgWin(msgContent);
          break;
        case "closeMsgWin":
          await this.closeMsgWin(msgContent);
          break;
      }
    } catch (e) {
      console.error("消息数据加载失败：" + msgContent)
      self.handleException("sdkBizServices", "安卓消息消费异常 -- " + bizType + " -- >", JSON.stringify(e.stack));
    }
  }

  /**
   * 初始化
   */
  async init() {
    // 初始化内部医生缓存
    await this.getAllWorkerIdList();

    // indPatient 内置全量患者數據
    await this.getAllWaitList();

    this.setHeadTitle();
  }

  /**
   * 刷新消息
   * @param str
   */
  async refreshMsg(str) {
    await Promise.all([
      // 刷新患者信息 -- 常规屏幕
      this.userWaitingRefresh(str),
      // indPatient 内置全量患者數據
      this.getAllWaitList(str)
    ]);
  }

  /**
   * 医生登录
   * @param obj
   */
  async doctorLogin(obj) {
    await this.init();
  }

  /**
   * 医生退出
   * @param obj
   */
  async doctorLogout(obj) {
    await this.init();
  }

  /**
   * 暂停
   * @param obj
   */
  pauseDoctor(obj) {
    this.pauseOrCancel(obj, true);
  }

  /**
   * 取消暂停
   * @param obj
   */
  cancelPause(obj) {
    this.pauseOrCancel(obj, false);
  }

  /**
   * 暂停/取消暂停
   * @param str
   * @param bool
   */
  pauseOrCancel(str, bool) {
    const obj = JSON.parse(resetLongToStr(str));
    let self = this.catcheInfo;
    self.waitingScreenWaitingData.currentList.map((item) => {
      // 号别 如果是号别的时候 需要传递号别ID
      if (self.waitingScreenWaitingData.queryRule == "2") {
        // 暂时不做任何处理
      } else {
        // 满足条件的医生
        if ((item.workStationIdList || [item.workStationId]).includes(obj.msgContent.terminalId)) {
          if (bool) {
            // 暂停接诊
            item.onlineStatus = "1";
          } else {
            // 取消暂停接诊
            item.onlineStatus = "0";
          }
        }
      }
    });
    // 给组件发送数据
    this.setPatientListInfo(self.waitingScreenWaitingData.currentList || []);
  }

  /**
   * 切屏数据刷新
   * @param str
   * @returns {Promise<void>}
   */
  async updateWaitScreenDoctors(str) {
    await this.getWaitingDataByWorkerId(str);
  }

  /**
   * 获取全部医生ID
   * @constructor
   */
  async getAllWorkerIdList() {
    let self = this.catcheInfo;
    try {
      const { data, code } = await UserWaitApi.getWaitList({
        terminalId: self.deviceInfo.screenId,
        terminalType: self.deviceInfo.screenType,
        businessType: self.deviceInfo.businessType,
        tenantId: self.deviceInfo.hospitalId,
        dataSource: self.apiType || "0",
      });
      if (code === 200) {
        // 设置缓存
        this.allWorkerList = data || [];
      }
    } catch (e) {
      self.handleException("sdkBizServices", "获取全量在线医生失败 getWaitList", JSON.stringify(e.stack));
    }
  }

  /**
   *  候诊屏 -- 获取当前屏 患者数据
   * @param str
   * @returns {Promise<void>}
   * @constructor
   */
  async getWaitingDataByWorkerId(str) {
    let self = this.catcheInfo;
    try {
      const arr = JSON.parse(resetLongToStr(str));
      const workerIdList = arr.map((item) => item.workerId);
      if (self.deviceInfo && self.deviceInfo.hospitalId) {
        const { data, code } = await UserWaitApi.getWaitingAll({
          workerIdList: workerIdList,
          waitNum: self.templateInfo.waitNum,
          terminalId: self.deviceInfo.screenId,
          terminalType: self.deviceInfo.screenType,
          businessType: self.deviceInfo.businessType,
          tenantId: self.deviceInfo.hospitalId,
          dataSource: self.apiType || "0",
          queryRule: self.waitingScreenWaitingData.queryRule,
          // 是否查询正在就诊  数据显示规则 1:否 ，2 是
          showCurrentPatient: self.waitingScreenWaitingData.showCurrentPatient,
          // 是否查询公共队列  数据显示规则 1:否 ，2 是
          showAllWaitPatient: self.waitingScreenWaitingData.showAllWaitPatient,
          // 候诊屏绑定号别 增加是否展示诊室开关  数据显示规则 1:否 ，2 是
          showRoomName: self.waitingScreenWaitingData.showRoomName,
          // 是否查询挂起数据
          containHangupData: self.waitingScreenWaitingData.containHangupData
        });
        if (code === 200) {
          // 缓存当前数据
          self.waitingScreenWaitingData.currentList = data || [];
          // 给组件发送数据
          this.setPatientListInfo(data || []);

          // 顶部动态科室设置
          if (true === self.trendsKey) {
            if (self.waitingScreenWaitingData.currentList.length > 0) {
              const deptName = self.waitingScreenWaitingData.currentList[0][self.contentKey] || "";
              this.setHeadTitle(deptName);
            }
          }
        }
      } else {
        // 给组件发送数据
        this.setPatientListInfo([]);
      }

    } catch (e) {
      self.handleWriteLog("sdkServices", `updateWaitScreenDoctors --> 患者解析错误${JSON.stringify(e.stack)}`);
    }
  }

  /**
   * 设置头部组件的名称
   */
  setHeadTitle(str) {
    // 通过索引获取坐标
    let headerItem = this.catcheInfo.modelMap["header"];
    let self = this.catcheInfo;
    if (headerItem && headerItem.options.config) {
      let configObj = headerItem.options[headerItem.options.config];
      if (!configObj.content || configObj.content === "") {
        if (str && true === self.trendsKey) {
          configObj.content = str || "";
        } else {
          configObj.content = self.deviceInfo.deviceName || "";
        }
      } else {
        if (str && true === self.trendsKey) {

          configObj.content = str || "";
        }
      }
    }
  }

  /**
   * 候诊屏 -- 局部患者刷新
   * @param str
   * @returns {Promise<void>}
   */
  async userWaitingRefresh(str) {
    let self = this.catcheInfo;
    try {
      const obj = JSON.parse(resetLongToStr(str));
      if (obj.msgContent && obj.msgContent["typeList"] && obj.msgContent["typeList"].includes("WAIT")) {
        const workerIdList = this.getWorkerIdListByRegisterObjId(self.waitingScreenWaitingData.currentList, obj.msgContent.registerObjId);
        const { data, code } = await UserWaitApi.getWaitingAll({
          workerIdList: workerIdList,
          waitNum: self.templateInfo.waitNum,
          terminalId: self.deviceInfo.screenId,
          terminalType: self.deviceInfo.screenType,
          businessType: self.deviceInfo.businessType,
          tenantId: self.deviceInfo.hospitalId,
          dataSource: self.apiType || "0",
          queryRule: self.waitingScreenWaitingData.queryRule,
          // 是否查询正在就诊  数据显示规则 1:否 ，2 是
          showCurrentPatient: self.waitingScreenWaitingData.showCurrentPatient,
          // 是否查询公共队列  数据显示规则 1:否 ，2 是
          showAllWaitPatient: self.waitingScreenWaitingData.showAllWaitPatient,
          // 候诊屏绑定号别 增加是否展示诊室开关  数据显示规则 1:否 ，2 是
          showRoomName: self.waitingScreenWaitingData.showRoomName,
          // 是否查询挂起数据
          containHangupData: self.waitingScreenWaitingData.containHangupData
        });
        if (code === 200) {
          // 重置数据
          data.map((item) => {
            self.waitingScreenWaitingData.currentList.map((row) => {
              if (self.apiType === "0") {
                // 号别 如果是号别的时候 需要传递号别ID
                if (self.waitingScreenWaitingData.queryRule === "2" || "6" === item.bindType) {
                  if (item.workerId === row.workerId) {
                    row.treatingPatient = item.treatingPatient;
                    row.waitPatientList = item.waitPatientList || [];
                    row.waitPatientCount = item.waitPatientCount || "";
                  }
                } else {
                  if ((row.workStationIdList || [row.workStationId]).includes(item.workStationId)) {
                    row.treatingPatient = item.treatingPatient;
                    row.waitPatientList = item.waitPatientList || [];
                    row.waitPatientCount = item.waitPatientCount || "";
                  }
                }
              } else {
                if (item.workerId === row.workerId) {
                  row.treatingPatient = item.treatingPatient;
                  row.waitPatientList = item.waitPatientList || [];
                  row.waitPatientCount = item.waitPatientCount || "";
                }
              }
            });
          });
          // 给组件发送数据
          this.setPatientListInfo(self.waitingScreenWaitingData.currentList);
        }
      }
    } catch (e) {
      self.handleException("sdkBizServices", "MtUserWaitingRefresh -> 候诊屏刷新异常", JSON.stringify(e.stack));
    }
  }


  /**
   * 全量刷新消息
   */
  async getAllWaitList(str) {
    if (this.currentInfo.screenDataType.indexOf("indPatient") > -1) {
      let self = this.catcheInfo;
      try {
        // 读取内部缓存医生信息 提升性能
        const workerIdList = this.allWorkerList.map((item) => item.workerId);
        if (workerIdList.length == 0) {
          this.setIndPatientInfo([]);
          return;
        }
        const { data, code } = await UserWaitApi.getWaitingAll({
          workerIdList: workerIdList,
          waitNum: self.templateInfo.waitNum,
          terminalId: self.deviceInfo.screenId,
          terminalType: self.deviceInfo.screenType,
          businessType: self.deviceInfo.businessType,
          tenantId: self.deviceInfo.hospitalId,
          dataSource: self.apiType || "0",
          queryRule: self.waitingScreenWaitingData.queryRule,
          // 是否查询正在就诊  数据显示规则 1:否 ，2 是
          showCurrentPatient: self.waitingScreenWaitingData.showCurrentPatient,
          // 是否查询公共队列  数据显示规则 1:否 ，2 是
          showAllWaitPatient: self.waitingScreenWaitingData.showAllWaitPatient,
          // 候诊屏绑定号别 增加是否展示诊室开关  数据显示规则 1:否 ，2 是
          showRoomName: self.waitingScreenWaitingData.showRoomName,
          // 是否查询挂起数据
          containHangupData: self.waitingScreenWaitingData.containHangupData
        });
        if (code === 200) {
          // 给组件发送数据
          this.setIndPatientInfo(data || []);
        } else {
          this.setIndPatientInfo([]);
        }
      } catch (e) {
        self.handleWriteLog("sdkServices", "getAllWaitList --> 获取全量队列数据错误" + JSON.stringify(e.stack));
      }
    }
  }

  /**
   * 候诊屏 -- 获取满足条件的医生ID
   * @param arr
   * @param rid
   * @returns {*[]}
   * @constructor
   */
  getWorkerIdListByRegisterObjId(arr, rid) {
    const worker = [];
    arr.map((item) => {
      if (item.registerObjIdList.includes(rid)) {
        // 号别 如果是号别的时候 需要传递号别ID
        worker.push(item.workerId);
      }
    });
    return worker;
  }

  /**
   * 候诊屏 -- 通过组件ID 更新数据
   * @param data
   * @constructor
   */
  setPatientListInfo(data) {
    let self = this.catcheInfo;
    try {
      const formRef = self.$refs["vFormRef"];
      if (formRef) {
        formRef.executeChildMethod(this.currentInfo?.id, "patientListInfo", data);
      }
    } catch (e) {
      self.handleException("sdkBizServices", "内部组件异常 -- patientListInfo -- >", JSON.stringify(e.stack));
    }
  }

  /**
   * 候诊屏 -- 设置候诊全量数据
   * @param data
   * @constructor
   */
  setIndPatientInfo(data) {
    let self = this.catcheInfo;
    try {
      const formRef = self.$refs["vFormRef"];
      if (formRef) {
        formRef.executeChildMethod(this.currentInfo?.id, "indPatientInfo", data);
      }
    } catch (e) {
      self.handleException("sdkBizServices", "内部组件异常 -- patientListInfo -- >", JSON.stringify(e.stack));
    }
  }

  /**
   * 打开弹窗
   * @param str
   */
  async openMsgWin(str) {
    const obj = JSON.parse(resetLongToStr(str));
    let self = this.catcheInfo;
    self.handleWriteLog("sdkServices -- 打开弹窗", str);
    // console.log(self._data, 'sdfd12121')

    // 弹窗需要原始数据
    self.waitingScreenMsgWinData.data = obj;
    self.waitingScreenMsgWinData.deptName = obj.msgContent.deptName;
    // 叫号器名称
    self.waitingScreenMsgWinData.workStationName = obj.msgContent.terminalName;
    self.waitingScreenMsgWinData.treatmentRoomName = obj.msgContent.treatmentRoomName;
    self.waitingScreenMsgWinData.deptShortName = obj.msgContent.deptShortName;
    self.waitingScreenMsgWinData.treatmentRoomShortName = obj.msgContent.treatmentRoomShortName;
    self.waitingScreenMsgWinData.registerObjName = obj.msgContent.treatingPatient ? obj.msgContent.treatingPatient.registerObjName : "";

    let treatingPatientList = obj.msgContent.treatingPatientList;
    if (treatingPatientList) {
      self.waitingScreenMsgWinData.currPatient = treatingPatientList || [];
    } else {
      self.waitingScreenMsgWinData.currPatient = obj.msgContent.treatingPatient ? [obj.msgContent.treatingPatient] : [];
      self.waitingScreenMsgWinData.currPatient = obj.msgContent.treatingPatient ? [obj.msgContent.treatingPatient] : [];
    }
    self.waitingScreenMsgWinData.waitPatient = obj.msgContent.waitingPatientList;
    self.waitingScreenMsgWinData.waitingAlert = obj.msgContent.waitingAlert;
    self.waitingScreenMsgWinData.treatingAlert = obj.msgContent.treatingAlert;
    self.waitingScreenMsgWinData.waitingVoiceContent = obj.msgContent.waitingVoiceContent;
    self.waitingScreenMsgWinData.treatingVoicePlayUrl = obj.msgContent.treatingVoicePlayUrl;
    // 正在就诊的控制文字
    self.waitingScreenMsgWinData.treatingVoiceContentConfig = obj.msgContent.treatingVoiceContentConfig;
    // 候诊语音播报的文案
    self.waitingScreenMsgWinData.waitingVoiceContent = obj.msgContent.waitingVoiceContent;
    let info = obj.msgContent.treatingVoiceContentConfig;
    if (!!info) {
      info.forEach((item) => {
        let key = item.type;
        let boolean = key === "orderNo" || key === "patientName" || key === "treatmentRoomName" || key === "deptName" || key === "workerName";
        if (boolean) {
          Reflect.set(item, "name", obj.msgContent.treatingPatient[key]);
          // 重置外层的科室或者诊室
          if (key === "treatmentRoomName") {
            Reflect.set(item, "name", obj.msgContent.treatmentRoomName);
          }
          if (key === "deptName") {
            Reflect.set(item, "name", obj.msgContent.deptName);
          }
          if (key === "workerName") {
            Reflect.set(item, "name", obj.msgContent.workerName);
          }
          if (key === "terminalName") {
            Reflect.set(item, "name", obj.msgContent.terminalName);
          }
        }
      });
      //  就诊语音的配置数值信息
      self.waitingScreenMsgWinData.currPatientInfo = info;
    }

    // 如果不展示候诊
    if (!obj.msgContent.waitingAlert) {
      self.waitingScreenMsgWinData.waitPatient = [];
    }
    if (self._data.layerNameKey === 'customize') {
      const formRef = self.$refs["vFormRef"];
      if (formRef) {
        formRef.executeChildMethod(this.currentInfo?.id, "openMsgWin", self.waitingScreenMsgWinData);
        // console.log(this.currentInfo?.id, self.waitingScreenMsgWinData, 'sdfd')
      }
    } else {
      // 配置是否展示就诊弹窗/候诊弹窗
      self.hasCallShow = !!(obj.msgContent.treatingAlert || obj.msgContent.waitingAlert);
    }
    // self.hasCallShow = !!(obj.msgContent.treatingAlert || obj.msgContent.waitingAlert);

  }

  /**
   * 关闭弹窗
   */
  closeMsgWin(str) {
    let self = this.catcheInfo;
    self.handleWriteLog("sdkServices -- 关闭弹窗", str);
    self.hasCallShow = false;
    if (self._data.layerNameKey === 'customize') {
      const formRef = self.$refs["vFormRef"];
      if (formRef) {
        formRef.executeChildMethod(this.currentInfo?.id, "closeMsgWin", self.waitingScreenMsgWinData);

      }
    } else {
      // 配置是否展示就诊弹窗/候诊弹窗
      self.hasCallShow = false;
    }
  }


}

export { WaitPatientObserverBiz };
